Academy

থ্রেডিং এবং কনকারেন্সি

Microsoft Technologies - সি শার্প (C#) - NCTB BOOK

থ্রেডিং এবং কনকারেন্সি সি# প্রোগ্রামিংয়ে একই সময়ে একাধিক কাজ সম্পন্ন করার জন্য ব্যবহৃত দুটি গুরুত্বপূর্ণ কনসেপ্ট। এগুলো কার্যক্ষমতা বাড়াতে এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে ব্যবহৃত হয়। তবে এই দুই কনসেপ্টের মধ্যে কিছু পার্থক্য আছে।


থ্রেডিং (Threading)

থ্রেড হলো একটি এক্সিকিউশন ইউনিট যা কোডের একটি নির্দিষ্ট অংশ চালায়। থ্রেডিং ব্যবহারের মাধ্যমে একটি প্রোগ্রামকে একাধিক থ্রেডে ভাগ করা যায়, যেখানে প্রতিটি থ্রেড নিজস্ব কাজ সম্পন্ন করে। সি# এ মাল্টিথ্রেডিং করতে System.Threading নেমস্পেস ব্যবহার করা হয়, যা Thread ক্লাস সরবরাহ করে।

থ্রেডিং এর উদাহরণ

using System;
using System.Threading;

public class Program
{
    public static void PrintNumbers()
    {
        for (int i = 1; i <= 5; i++)
        {
            Console.WriteLine("Number: " + i);
            Thread.Sleep(1000); // এক সেকেন্ড অপেক্ষা
        }
    }

    public static void Main()
    {
        Thread thread = new Thread(PrintNumbers);
        thread.Start();

        Console.WriteLine("Main thread is running independently.");
    }
}

থ্রেডিং এর বৈশিষ্ট্য

  • আলাদা থ্রেডে কাজ সম্পন্ন: প্রতিটি থ্রেড আলাদা এক্সিকিউশন ইউনিট হিসেবে কাজ করে।
  • পারফরম্যান্স বৃদ্ধি: একাধিক থ্রেড একসাথে কাজ করার মাধ্যমে প্রোগ্রামের পারফরম্যান্স বাড়ানো যায়।
  • ব্যবহার: CPU-এর মাল্টিকোর এবং মাল্টি-প্রসেসরের সুবিধা নেওয়া যায়।

কনকারেন্সি (Concurrency)

কনকারেন্সি হলো এমন একটি পদ্ধতি যেখানে একটি প্রোগ্রাম একসাথে একাধিক কাজ বা টাস্ক সম্পন্ন করতে সক্ষম। কনকারেন্সির মাধ্যমে প্রোগ্রামের বিভিন্ন টাস্ক একই সময়ে একসাথে কাজ করতে পারে এবং একে অন্যের সাথে সমন্বয় করে চলে।

কনকারেন্সি ব্যবহারে অনেক সময় অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং করা হয়, যাতে কোনো কাজ সম্পন্ন হতে অপেক্ষা না করে অন্য কাজ শুরু করা যায়। সি# এ async এবং await কিওয়ার্ড ব্যবহার করে কনকারেন্ট প্রোগ্রামিং করা যায়।

কনকারেন্সির উদাহরণ (Asynchronous Programming)

using System;
using System.Threading.Tasks;

public class Program
{
    public static async Task PrintNumbersAsync()
    {
        for (int i = 1; i <= 5; i++)
        {
            Console.WriteLine("Number: " + i);
            await Task.Delay(1000); // এক সেকেন্ড অপেক্ষা (অ্যাসিঙ্ক্রোনাস)
        }
    }

    public static async Task Main()
    {
        Task task = PrintNumbersAsync();

        Console.WriteLine("Main thread is not blocked.");
        
        await task; // টাস্কের সম্পন্ন হওয়ার জন্য অপেক্ষা
        Console.WriteLine("All tasks are completed.");
    }
}

কনকারেন্সির বৈশিষ্ট্য

  • একাধিক টাস্ক একসাথে চালানো: বিভিন্ন টাস্ক একই সময়ে চালানো যায়।
  • অ্যাসিঙ্ক্রোনাস কাজ: কাজের ফলাফল আসতে সময় লাগলে অন্য কাজ চালানো যায়।
  • Responsive UI: ব্যবহারকারী ইন্টারফেস দ্রুত সাড়া দেয়, কারণ থ্রেড ব্লক না হয়ে অপেক্ষা করে।

থ্রেডিং বনাম কনকারেন্সি

বৈশিষ্ট্যথ্রেডিংকনকারেন্সি
সংজ্ঞাএকটি নির্দিষ্ট কাজ সম্পন্ন করার জন্য আলাদা থ্রেড তৈরি করাএকসাথে একাধিক কাজ চালানো
প্রকৃতিএকাধিক থ্রেড ব্যবহার করে কাজ সম্পন্ন করাঅ্যাসিঙ্ক্রোনাস এবং সামান্তরালভাবে কাজ সম্পন্ন করা
ব্যবহারCPU-ইনটেনসিভ কাজের জন্যI/O-ইনটেনসিভ এবং দীর্ঘ সময়ের কাজের জন্য
কোড সিনট্যাক্সThread ক্লাস, Start(), Join()async, await, এবং Task
উদাহরণপ্রিন্টিং, হিসাবের কাজফাইল পড়া, ডেটাবেস অ্যাক্সেস, API কল

মাল্টিথ্রেডিং এবং কনকারেন্সি একসাথে ব্যবহার

অনেক সময় থ্রেডিং এবং কনকারেন্সি একসাথে ব্যবহার করে সমান্তরাল প্রোগ্রামিং করা হয়, যা দ্রুত এবং কার্যকরী সমাধান তৈরি করতে সহায়ক হয়।

উদাহরণ: মাল্টিথ্রেডিং এবং কনকারেন্সি একসাথে ব্যবহার

using System;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
    public static async Task PrintNumbersAsync()
    {
        for (int i = 1; i <= 5; i++)
        {
            Console.WriteLine("Number: " + i);
            await Task.Delay(1000); // অ্যাসিঙ্ক্রোনাস
        }
    }

    public static void PrintLetters()
    {
        for (char letter = 'A'; letter <= 'E'; letter++)
        {
            Console.WriteLine("Letter: " + letter);
            Thread.Sleep(1000); // থ্রেডিং
        }
    }

    public static async Task Main()
    {
        Task numberTask = PrintNumbersAsync(); // অ্যাসিঙ্ক্রোনাস টাস্ক
        Thread letterThread = new Thread(PrintLetters); // থ্রেড তৈরি

        letterThread.Start();
        await numberTask;

        letterThread.Join(); // থ্রেড সম্পন্ন হওয়ার জন্য অপেক্ষা
        Console.WriteLine("All tasks completed.");
    }
}

ব্যাখ্যা

  • PrintNumbersAsync মেথডটি একটি অ্যাসিঙ্ক্রোনাস টাস্ক হিসেবে কাজ করে।
  • PrintLetters মেথডটি একটি আলাদা থ্রেডে চালানো হয়।
  • এই দুই কাজ একসাথে চলতে পারে এবং শেষে Main থ্রেড নিশ্চিত করে যে সব কাজ সম্পন্ন হয়েছে।

সংক্ষেপে

  • থ্রেডিং: একাধিক থ্রেড ব্যবহার করে একসাথে কাজ সম্পন্ন করা।
  • কনকারেন্সি: একাধিক কাজ একসাথে বা অ্যাসিঙ্ক্রোনাসভাবে সম্পন্ন করা।
  • মাল্টিথ্রেডিং: CPU-ইনটেনসিভ কাজের জন্য কার্যকরী।
  • অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং: I/O-ইনটেনসিভ কাজের জন্য কার্যকরী।

সি# এ মাল্টিথ্রেডিং এবং কনকারেন্সি ব্যবহার করে দ্রুত এবং রেসপন্সিভ প্রোগ্রাম তৈরি করা যায়। থ্রেডিং এবং কনকারেন্সি বুঝে এবং ব্যবহার করে প্রোগ্রামের কার্যক্ষমতা অনেক বৃদ্ধি করা যায়।

Content added By

মাল্টিথ্রেডিং এবং থ্রেড ক্লাস

সি# এ মাল্টিথ্রেডিং একটি গুরুত্বপূর্ণ ফিচার, যা একই সময়ে একাধিক কাজ সম্পন্ন করতে সহায়তা করে। মাল্টিথ্রেডিংয়ের মাধ্যমে একটি প্রোগ্রামে একাধিক থ্রেড চালানো যায়, যাতে তারা সমান্তরালে কাজ করে এবং প্রোগ্রামের কার্যক্ষমতা বাড়ায়। সি# এ মাল্টিথ্রেডিং করতে Thread ক্লাস ব্যবহৃত হয়, যা System.Threading নেমস্পেসের অংশ।


মাল্টিথ্রেডিং এর ধারণা

একটি থ্রেড হলো কোড এক্সিকিউশনের একটি নির্দিষ্ট পথ। মাল্টিথ্রেডিং এর মাধ্যমে প্রোগ্রামে একাধিক থ্রেড তৈরি করে একই সময়ে বিভিন্ন কাজ চালানো যায়। এতে:

  • পারফরম্যান্স বাড়ানো যায়: একাধিক কাজ একই সময়ে করা যায়।
  • Responsive UI: গ্রাফিকাল ইউজার ইন্টারফেসে (GUI) মাল্টিথ্রেডিং ব্যবহার করে প্রোগ্রামকে বেশি সাড়া জাগানো যায়।

Thread ক্লাস

Thread ক্লাস ব্যবহার করে একটি নতুন থ্রেড তৈরি এবং নিয়ন্ত্রণ করা যায়। এটি বিভিন্ন মেথড ও প্রোপার্টি সরবরাহ করে, যা থ্রেডের জীবনচক্র নিয়ন্ত্রণে সহায়তা করে।

থ্রেড তৈরি করা

একটি নতুন থ্রেড তৈরি করতে Thread ক্লাস ব্যবহার করে ThreadStart ডেলিগেটের মাধ্যমে নির্দিষ্ট মেথডে থ্রেড সেট করা হয়।

using System;
using System.Threading;

public class Program
{
    public static void PrintNumbers()
    {
        for (int i = 1; i <= 5; i++)
        {
            Console.WriteLine(i);
            Thread.Sleep(1000); // এক সেকেন্ড অপেক্ষা
        }
    }

    public static void Main()
    {
        // থ্রেড তৈরি করা
        Thread thread = new Thread(PrintNumbers);
        thread.Start();

        Console.WriteLine("Main thread is running independently.");
    }
}

ব্যাখ্যা

  1. Thread Creation: new Thread(PrintNumbers) দিয়ে একটি নতুন থ্রেড তৈরি করা হয়েছে, যা PrintNumbers মেথডে কাজ করবে।
  2. Thread.Start(): Start() মেথড দিয়ে থ্রেড চালু করা হয়েছে।
  3. Thread.Sleep(1000): Sleep মেথড দিয়ে থ্রেড এক সেকেন্ড অপেক্ষা করবে (milliseconds হিসাবে), অর্থাৎ প্রতিটি সংখ্যা এক সেকেন্ডের ব্যবধানে প্রিন্ট করবে।

থ্রেডের প্রাধান্য (Priority)

থ্রেডের Priority সেট করে কাজের গুরুত্ব অনুযায়ী থ্রেড চালানো যায়। ThreadPriority এনাম ব্যবহার করে থ্রেডের প্রাধান্য নির্ধারণ করা হয়, যেমন Highest, AboveNormal, Normal, BelowNormal, এবং Lowest

thread.Priority = ThreadPriority.Highest;

থ্রেড স্থগিত এবং পুনরায় শুরু (Pause and Resume)

সি# এ থ্রেডকে Sleep মেথড দিয়ে সাময়িকভাবে স্থগিত করা যায়, তবে থ্রেডকে পুনরায় শুরু করার জন্য Suspend এবং Resume মেথড এখন আর ব্যবহৃত হয় না, কারণ এগুলো ডেডলকের কারণ হতে পারে। বরং থ্রেড কন্ট্রোলের জন্য মানসিক কোড লজিক ব্যবহার করা হয়।


থ্রেড জয়েন (Thread Join)

Join() মেথড ব্যবহার করে বর্তমান থ্রেডকে অপেক্ষা করানো যায় যতক্ষণ না নির্দিষ্ট থ্রেড কাজ শেষ করে।

Thread thread = new Thread(PrintNumbers);
thread.Start();
thread.Join(); // Main thread waits until this thread completes

Console.WriteLine("Main thread resumes after the other thread completes.");

ব্যাখ্যা

thread.Join() ব্যবহার করলে মেইন থ্রেড অপেক্ষা করবে যতক্ষণ না PrintNumbers থ্রেড কাজ শেষ করে। এরপর মেইন থ্রেড পরবর্তী কোড চালাবে।


থ্রেড সিঙ্ক্রোনাইজেশন

যদি একাধিক থ্রেড একই রিসোর্স অ্যাক্সেস করে, তবে ডেটা ইনকনসিস্টেন্সি ঘটতে পারে। এই সমস্যা সমাধানের জন্য lock ব্যবহার করা হয়, যা একবারে কেবলমাত্র একটি থ্রেডকে রিসোর্স অ্যাক্সেস করার অনুমতি দেয়।

using System;
using System.Threading;

public class Program
{
    private static readonly object lockObj = new object();

    public static void PrintNumbers()
    {
        lock (lockObj)
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine(i);
                Thread.Sleep(500);
            }
        }
    }

    public static void Main()
    {
        Thread thread1 = new Thread(PrintNumbers);
        Thread thread2 = new Thread(PrintNumbers);

        thread1.Start();
        thread2.Start();
    }
}

ব্যাখ্যা

  1. lock: lock (lockObj) দিয়ে একবারে একটি থ্রেডকে PrintNumbers মেথডের মধ্যে এক্সিকিউট করার অনুমতি দেওয়া হয়েছে।
  2. lockObj অবজেক্ট দ্বারা সিঙ্ক্রোনাইজেশন নিশ্চিত করা হয়েছে, যাতে একই সময়ে কেবলমাত্র একটি থ্রেডই PrintNumbers মেথড অ্যাক্সেস করতে পারে।

থ্রেড অ্যাবোর্ট (Abort)

Abort() মেথড ব্যবহার করে থ্রেডকে বন্ধ করা যায়, তবে এটি প্রায়শই এড়িয়ে চলা হয় কারণ এটি থ্রেডের জীবনচক্রে সমস্যা তৈরি করতে পারে।

Thread thread = new Thread(PrintNumbers);
thread.Start();
thread.Abort(); // Thread forcibly terminated

নোট: থ্রেড অ্যাবোর্ট অপ্রচলিত এবং এটি ব্যবহার করা বিপজ্জনক হতে পারে। Abort এর পরিবর্তে থ্রেড বন্ধ করার জন্য বিকল্প পদ্ধতি ব্যবহার করা উচিত, যেমন একটি ফ্ল্যাগ পরিবর্তন করে থ্রেড বন্ধ করা।


একটি পূর্ণ উদাহরণ যেখানে মাল্টিপল থ্রেড ব্যবহার করা হয়েছে

csharp

Copy code

using System;
using System.Threading;

public class Program
{
    public static void PrintNumbers()
    {
        for (int i = 1; i <= 5; i++)
        {
            Console.WriteLine("Number: " + i);
            Thread.Sleep(500);
        }
    }

    public static void PrintLetters()
    {
        for (char letter = 'A'; letter <= 'E'; letter++)
        {
            Console.WriteLine("Letter: " + letter);
            Thread.Sleep(500);
        }
    }

    public static void Main()
    {
        Thread thread1 = new Thread(PrintNumbers);
        Thread thread2 = new Thread(PrintLetters);

        thread1.Start();
        thread2.Start();

        thread1.Join();
        thread2.Join();

        Console.WriteLine("Both threads have completed.");
    }
}

ব্যাখ্যা

  1. PrintNumbers এবং PrintLetters নামে দুটি আলাদা মেথড আছে।
  2. thread1 এবং thread2 নামে দুটি থ্রেড তৈরি করে সেগুলোকে দুটি মেথডে এসাইন করা হয়েছে।
  3. thread1.Start() এবং thread2.Start() দিয়ে থ্রেড চালানো হয়েছে এবং Join() দিয়ে নিশ্চিত করা হয়েছে যে দুই থ্রেডের কাজ শেষ হলে পরবর্তী কোড চালাবে।

সংক্ষেপে

  • Thread ক্লাস: মাল্টিথ্রেডিং করতে ব্যবহার করা হয়।
  • Start(): থ্রেড চালু করে।
  • Sleep(): থ্রেডকে সাময়িকভাবে স্থগিত করে।
  • Join(): মেইন থ্রেডকে অপেক্ষা করানো হয় যতক্ষণ না নির্দিষ্ট থ্রেড শেষ হয়।
  • Priority: থ্রেডের প্রাধান্য নির্ধারণ করতে ব্যবহৃত।
  • lock: রিসোর্সে একাধিক থ্রেডের এক্সেস সিঙ্ক্রোনাইজ করতে ব্যবহৃত হয়।
  • Abort(): থ্রেড বন্ধ করতে ব্যবহৃত, তবে প্রায়শই এড়িয়ে চলা হয়।

সি# এ মাল্টিথ্রেডিং ব্যবহারে প্রোগ্রামের পারফরম্যান্স বাড়ানো যায় এবং একই সাথে একাধিক কাজ করা সম্ভব হয়।

 

 

Content added By

থ্রেড সিঙ্ক্রোনাইজেশন

সি# এ থ্রেড সিঙ্ক্রোনাইজেশন এমন একটি প্রক্রিয়া, যার মাধ্যমে একাধিক থ্রেড একই রিসোর্সে সমান্তরালে অ্যাক্সেস করতে চায় এমন সময়ে ডেটা ইনকনসিস্টেন্সি রোধ করা যায়। এটি মূলত থ্রেড সেফটি নিশ্চিত করে, যাতে একই সময়ে কেবলমাত্র একটি থ্রেড নির্দিষ্ট রিসোর্স বা কোড ব্লক এক্সেস করতে পারে।

থ্রেড সিঙ্ক্রোনাইজেশনের চাহিদা

যখন একাধিক থ্রেড একই রিসোর্স বা ডেটা শেয়ার করে এবং তা পরিবর্তন করতে চায়, তখন ডেটা ইনকনসিস্টেন্সি বা "race condition" হতে পারে। এই সমস্যাগুলি দূর করতে সিঙ্ক্রোনাইজেশন প্রয়োজন হয়।


সি# এ থ্রেড সিঙ্ক্রোনাইজেশনের উপায়

সি# এ থ্রেড সিঙ্ক্রোনাইজেশনের জন্য বিভিন্ন টুলস রয়েছে। এর মধ্যে কয়েকটি সাধারণ টুল হলো:

  1. lock কিওয়ার্ড
  2. Monitor ক্লাস
  3. Mutex ক্লাস
  4. Semaphore ক্লাস

১. lock কিওয়ার্ড

lock কিওয়ার্ড সাধারণত থ্রেড সিঙ্ক্রোনাইজেশনের সবচেয়ে সহজ উপায় হিসেবে ব্যবহৃত হয়। এটি একটি নির্দিষ্ট কোড ব্লককে একবারে কেবলমাত্র একটি থ্রেডের জন্য অ্যাক্সেসযোগ্য করে।

using System;
using System.Threading;

public class Program
{
    private static readonly object lockObj = new object();

    public static void PrintNumbers()
    {
        lock (lockObj)
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine(i);
                Thread.Sleep(500);
            }
        }
    }

    public static void Main()
    {
        Thread thread1 = new Thread(PrintNumbers);
        Thread thread2 = new Thread(PrintNumbers);

        thread1.Start();
        thread2.Start();
    }
}

ব্যাখ্যা

  • lockObj: একটি অবজেক্ট যা lock ব্লকে ব্যবহার করা হয়। এটি একবারে কেবল একটি থ্রেডকে PrintNumbers মেথড অ্যাক্সেস করতে দেয়।
  • lock (lockObj): এই ব্লকটিতে একবারে কেবলমাত্র একটি থ্রেড প্রবেশ করতে পারে। অন্য থ্রেডকে অপেক্ষা করতে হয় যতক্ষণ না প্রথম থ্রেড কাজ শেষ করে।

২. Monitor ক্লাস

Monitor ক্লাস lock এর মতো কাজ করে, তবে এটি বেশি নিয়ন্ত্রণ দেয়। Monitor.Enter একটি কোড ব্লককে লক করে এবং Monitor.Exit দিয়ে লক মুক্ত করে।

using System;
using System.Threading;

public class Program
{
    private static readonly object lockObj = new object();

    public static void PrintNumbers()
    {
        Monitor.Enter(lockObj);
        try
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine(i);
                Thread.Sleep(500);
            }
        }
        finally
        {
            Monitor.Exit(lockObj);
        }
    }

    public static void Main()
    {
        Thread thread1 = new Thread(PrintNumbers);
        Thread thread2 = new Thread(PrintNumbers);

        thread1.Start();
        thread2.Start();
    }
}

ব্যাখ্যা

  • Monitor.Enter(lockObj): lockObj অবজেক্ট লক করে।
  • Monitor.Exit(lockObj): lockObj অবজেক্টের লক মুক্ত করে।
  • try-finally ব্লক: Monitor.Exit অবশ্যই চালানোর জন্য finally ব্লক ব্যবহার করা হয়।

৩. Mutex (Mutual Exclusion)

Mutex একাধিক প্রক্রিয়া থেকে অ্যাক্সেস নিয়ন্ত্রণের জন্য ব্যবহৃত হয়। এটি lock বা Monitor থেকে বেশি কার্যকর, কারণ এটি কম্পিউটারের বিভিন্ন প্রক্রিয়ায় ব্যবহারযোগ্য।

using System;
using System.Threading;

public class Program
{
    private static Mutex mutex = new Mutex();

    public static void PrintNumbers()
    {
        mutex.WaitOne(); // Mutex লক করা
        try
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine(i);
                Thread.Sleep(500);
            }
        }
        finally
        {
            mutex.ReleaseMutex(); // Mutex মুক্ত করা
        }
    }

    public static void Main()
    {
        Thread thread1 = new Thread(PrintNumbers);
        Thread thread2 = new Thread(PrintNumbers);

        thread1.Start();
        thread2.Start();
    }
}

ব্যাখ্যা

  • WaitOne(): এটি থ্রেডকে মিউটেক্স লক করতে বলে এবং অন্য থ্রেডকে অপেক্ষা করতে দেয়।
  • ReleaseMutex(): মিউটেক্স মুক্ত করে, যাতে অন্য থ্রেড এটিকে অ্যাক্সেস করতে পারে।
  • Mutex একাধিক প্রক্রিয়া বা অ্যাপ্লিকেশন থেকে শেয়ার্ড রিসোর্স সিঙ্ক্রোনাইজ করতে সহায়ক।

৪. Semaphore

Semaphore একবারে একাধিক থ্রেডকে নির্দিষ্ট রিসোর্সে প্রবেশের অনুমতি দেয়। উদাহরণস্বরূপ, আপনি চাইলে একই সময়ে দুইটি থ্রেডকে কাজ করতে দিতে পারেন, তবে তৃতীয় থ্রেডকে অপেক্ষা করাতে পারেন যতক্ষণ না অন্য দুটি থ্রেড কাজ শেষ করে।

using System;
using System.Threading;

public class Program
{
    // একসাথে ২টি থ্রেড প্রবেশের অনুমতি
    private static Semaphore semaphore = new Semaphore(2, 2);

    public static void PrintNumbers()
    {
        semaphore.WaitOne(); // Semaphore লক করা
        try
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " - " + i);
                Thread.Sleep(500);
            }
        }
        finally
        {
            semaphore.Release(); // Semaphore মুক্ত করা
        }
    }

    public static void Main()
    {
        Thread thread1 = new Thread(PrintNumbers);
        Thread thread2 = new Thread(PrintNumbers);
        Thread thread3 = new Thread(PrintNumbers);

        thread1.Start();
        thread2.Start();
        thread3.Start();
    }
}

ব্যাখ্যা

  • new Semaphore(2, 2): Semaphore একসাথে ২টি থ্রেডকে অ্যাক্সেসের অনুমতি দেয়।
  • WaitOne(): Semaphore লক করে এবং অন্য থ্রেডকে অপেক্ষা করতে বলে।
  • Release(): Semaphore মুক্ত করে, যাতে অন্য থ্রেড রিসোর্সে প্রবেশ করতে পারে।

সংক্ষেপে থ্রেড সিঙ্ক্রোনাইজেশন

  • lock: সহজ ও কার্যকর উপায়; একবারে একটি থ্রেডকে রিসোর্সে অ্যাক্সেস করতে দেয়।
  • Monitor: lock এর মতোই তবে এটি বেশি নিয়ন্ত্রণ দেয়, যেমন Enter এবং Exit মেথড।
  • Mutex: কম্পিউটারের বিভিন্ন প্রক্রিয়ায় ব্যবহার করা যায় এবং একাধিক অ্যাপ্লিকেশনের মধ্যে রিসোর্স সিঙ্ক্রোনাইজ করতে সাহায্য করে।
  • Semaphore: একসাথে নির্দিষ্ট সংখ্যক থ্রেডকে রিসোর্সে প্রবেশের অনুমতি দেয়।

সি# এ থ্রেড সিঙ্ক্রোনাইজেশন ব্যবহার করে একাধিক থ্রেডের মধ্যে শেয়ার্ড রিসোর্স ব্যবহারে সংঘাত বা ডেটা ইনকনসিস্টেন্সি এড়ানো যায় এবং প্রোগ্রামকে সঠিকভাবে পরিচালনা করা সম্ভব হয়।

Content added By

async এবং await কীওয়ার্ড

সি# এ async এবং await কীওয়ার্ডগুলি ব্যবহার করে অ্যাসিনক্রোনাস প্রোগ্রামিং সহজে করা যায়। অ্যাসিনক্রোনাস প্রোগ্রামিংয়ের মাধ্যমে প্রোগ্রামকে নির্দিষ্ট কিছু কাজ সম্পন্ন হওয়া পর্যন্ত অপেক্ষা করতে হয় না, বরং সে সময়ে অন্য কাজগুলোও সম্পন্ন করতে পারে।

async এবং await কীওয়ার্ড

  • async: মেথডের সাথে যুক্ত করে জানানো হয় যে এই মেথডটি অ্যাসিনক্রোনাস, অর্থাৎ এটি একটি দীর্ঘমেয়াদি কাজ করার সময় মেইন থ্রেডকে ব্লক করবে না।
  • await: দীর্ঘমেয়াদি কাজ শেষ না হওয়া পর্যন্ত অপেক্ষা করতে ব্যবহৃত হয়। এটি async মেথডের ভিতরে কাজ করে এবং কেবল async মেথডেই ব্যবহার করা যায়।

উদাহরণ দিয়ে async এবং await ব্যাখ্যা

নিচে async এবং await কীভাবে কাজ করে তার একটি উদাহরণ দেওয়া হলো। এখানে একটি অ্যাসিনক্রোনাস মেথড ব্যবহার করে একটি কাজ সম্পন্ন করা হয়েছে।

উদাহরণ ১: বেসিক async এবং await ব্যবহারের উদাহরণ

using System;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main()
    {
        Console.WriteLine("Starting work...");
        
        // অ্যাসিনক্রোনাস মেথড কল করা
        await DoWorkAsync();
        
        Console.WriteLine("Work completed.");
    }

    public static async Task DoWorkAsync()
    {
        Console.WriteLine("Working...");
        await Task.Delay(3000); // ৩ সেকেন্ড অপেক্ষা করে
        Console.WriteLine("Work is done!");
    }
}

ব্যাখ্যা

  1. async Task Main(): Main মেথডে async ব্যবহার করে জানানো হয়েছে যে এটি অ্যাসিনক্রোনাস মেথড।
  2. await DoWorkAsync(): DoWorkAsync মেথডটি কল করা হয়েছে এবং await ব্যবহার করে বলা হয়েছে যে এটি সম্পন্ন হওয়া পর্যন্ত অপেক্ষা করবে।
  3. Task.Delay(3000): Task.Delay একটি ৩ সেকেন্ডের ডিলে তৈরি করে, যা অ্যাসিনক্রোনাস টাইমার হিসেবে কাজ করে।

আউটপুট:

Starting work...
Working...
Work is done!
Work completed.

এই প্রক্রিয়ায় Task.Delay কাজের সময় মেইন থ্রেডকে ব্লক না করে অপেক্ষা করে। ফলে অন্যান্য কাজ সমান্তরালে চলতে পারে।


উদাহরণ ২: async এবং await সহ ডেটা ফেচ করা

ধরা যাক, একটি মেথড সার্ভার থেকে ডেটা ফেচ করবে। এই কাজ সম্পন্ন করতে কিছুটা সময় লাগতে পারে, তাই async এবং await ব্যবহার করলে মেইন থ্রেড ব্লক না হয়ে অপেক্ষা করবে এবং ডেটা ফেচ হওয়ার পরই কেবল পরবর্তী কাজ সম্পন্ন করবে।

using System;
using System.Net.Http;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main()
    {
        Console.WriteLine("Fetching data...");

        // অ্যাসিনক্রোনাস মেথড কল করে ডেটা ফেচ করা
        string data = await FetchDataAsync();
        
        Console.WriteLine("Data fetched: " + data);
    }

    public static async Task<string> FetchDataAsync()
    {
        using (HttpClient client = new HttpClient())
        {
            // কোনো URL থেকে ডেটা ফেচ করা
            string result = await client.GetStringAsync("https://jsonplaceholder.typicode.com/todos/1");
            return result;
        }
    }
}

ব্যাখ্যা

  1. async Task<string> FetchDataAsync(): FetchDataAsync একটি অ্যাসিনক্রোনাস মেথড যা একটি স্ট্রিং রিটার্ন করে।
  2. await client.GetStringAsync(...): এই মেথডটি অনলাইনে একটি GET রিকোয়েস্ট পাঠায় এবং রেসপন্স না আসা পর্যন্ত অপেক্ষা করে।
  3. await FetchDataAsync(): FetchDataAsync থেকে ডেটা রিটার্ন না হওয়া পর্যন্ত অপেক্ষা করে।

আউটপুট:

Fetching data...
Data fetched: {id: 1, title: "...", ...}

এই উদাহরণে await ব্যবহার করে সার্ভার থেকে ডেটা ফেচ করা হচ্ছে। অ্যাসিনক্রোনাস প্রোগ্রামিং এর মাধ্যমে await নিশ্চিত করে যে ডেটা সম্পূর্ণভাবে লোড হওয়া পর্যন্ত মেইন থ্রেড অপেক্ষা করবে, তবে ব্লক হবে না।


async এবং await ব্যবহারের নিয়ম ও সুবিধা

async মেথডের রিটার্ন টাইপ:

  • void: ইভেন্ট হ্যান্ডলার মেথডে ব্যবহৃত হয়।
  • Task: যখন মেথড কিছু রিটার্ন করবে না।
  • Task<T>: যখন মেথড কিছু রিটার্ন করবে, যেমন Task<string>, যেখানে string রিটার্ন হবে।

await কেবল async মেথডের মধ্যে ব্যবহার করা যায়: await ব্যবহারের জন্য মেথডে async কিওয়ার্ড ব্যবহার করা প্রয়োজন।

পারফরম্যান্স বৃদ্ধি: অ্যাসিনক্রোনাস প্রোগ্রামিং ব্যবহার করে প্রোগ্রামের পারফরম্যান্স উন্নত করা যায়। এতে UI ব্লক না করে সমান্তরালে কাজ করতে পারে।

সহজ ও সংক্ষিপ্ত কোড: async এবং await এর মাধ্যমে জটিল অ্যাসিনক্রোনাস প্রোগ্রামিং সহজে করা যায় এবং কোডও সংক্ষিপ্ত হয়।


সংক্ষেপে

  • async: মেথডকে অ্যাসিনক্রোনাস ঘোষণা করে এবং অ্যাসিনক্রোনাস কাজ পরিচালনার জন্য প্রস্তুত করে।
  • await: অ্যাসিনক্রোনাস কাজ সম্পূর্ণ না হওয়া পর্যন্ত অপেক্ষা করে এবং কাজ শেষ হলে পরবর্তী লাইন এক্সিকিউট করে।
  • পারফরম্যান্স ও রেসপন্সিভনেস বৃদ্ধি: অ্যাসিনক্রোনাস প্রোগ্রামিং ব্যবহার করে অ্যাপ্লিকেশনকে ব্লক না করে চলমান রাখা যায়।

async এবং await এর ব্যবহার করে সি# এ অ্যাসিনক্রোনাস প্রোগ্রামিং সহজে করা যায়, যা প্রোগ্রামের কার্যক্ষমতা এবং রেসপন্সিভনেস বৃদ্ধি করে।

Content added By

টাস্ক প্যারালাল লাইব্রেরি (TPL)

টাস্ক প্যারালাল লাইব্রেরি (Task Parallel Library বা TPL) সি# এ একটি শক্তিশালী কনকারেন্সি লাইব্রেরি, যা সমান্তরাল প্রোগ্রামিং (Parallel Programming) সহজ করে। এটি .NET ফ্রেমওয়ার্কের System.Threading.Tasks নেমস্পেসের অংশ এবং টাস্ক-ভিত্তিক কাজগুলো সমান্তরালে চালানোর জন্য ডিজাইন করা হয়েছে। TPL এর মাধ্যমে প্যারালাল প্রোগ্রামিংয়ের জটিলতা কমানো যায় এবং প্রোগ্রামের কার্যক্ষমতা বৃদ্ধি করা যায়।

TPL এর বৈশিষ্ট্য

  • সহজ টাস্ক ব্যবস্থাপনা: TPL ব্যবহার করে টাস্ক তৈরি, পরিচালনা এবং ট্র্যাক করা সহজ।
  • সহজ কনকারেন্সি নিয়ন্ত্রণ: একাধিক কাজকে সমান্তরালে চালানোর সুবিধা।
  • Error Handling: TPL সহজে এক্সেপশন হ্যান্ডলিং এবং টাস্ক ক্যাঙ্কেল করার জন্য ব্যবস্থা সরবরাহ করে।

TPL এর গুরুত্বপূর্ণ কিছু ক্লাস ও মেথড

  • Task: টাস্ক তৈরি ও পরিচালনা করতে ব্যবহৃত।
  • Task.Run: একটি টাস্ক শুরু করে।
  • Task.WhenAll এবং Task.WhenAny: একাধিক টাস্ককে একত্রে পরিচালনা করতে ব্যবহৃত।
  • Parallel.For এবং Parallel.ForEach: লুপকে সমান্তরালে চালানোর জন্য ব্যবহৃত।

টাস্ক তৈরি ও ব্যবহার

Task ক্লাস দিয়ে টাস্ক তৈরি করা হয় এবং Start() মেথড বা Task.Run দিয়ে টাস্ক চালানো যায়।

উদাহরণ: Task ক্লাস ব্যবহার করে টাস্ক তৈরি

using System;
using System.Threading.Tasks;

public class Program
{
    public static void Main()
    {
        Task task = new Task(() =>
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Task running: " + i);
            }
        });

        task.Start();
        task.Wait(); // টাস্ক শেষ হওয়ার জন্য অপেক্ষা

        Console.WriteLine("Task completed.");
    }
}

Task.Run() ব্যবহার করে টাস্ক চালানো

Task.Run একটি নতুন টাস্ক তৈরি এবং চালানোর সহজ পদ্ধতি।

using System;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main()
    {
        Task task = Task.Run(() =>
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Running task: " + i);
            }
        });

        await task; // টাস্ক শেষ হওয়া পর্যন্ত অপেক্ষা

        Console.WriteLine("Task is complete.");
    }
}

একাধিক টাস্ক পরিচালনা (Task.WhenAll এবং Task.WhenAny)

Task.WhenAll এবং Task.WhenAny মেথডগুলো একাধিক টাস্ক চালানো এবং একসাথে পরিচালনা করতে ব্যবহৃত হয়।

উদাহরণ: Task.WhenAll দিয়ে একাধিক টাস্ক একসাথে চালানো

using System;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main()
    {
        Task task1 = Task.Run(() => Console.WriteLine("Task 1"));
        Task task2 = Task.Run(() => Console.WriteLine("Task 2"));
        Task task3 = Task.Run(() => Console.WriteLine("Task 3"));

        await Task.WhenAll(task1, task2, task3); // সব টাস্ক শেষ হওয়া পর্যন্ত অপেক্ষা

        Console.WriteLine("All tasks completed.");
    }
}

Task.WhenAny দিয়ে একটিমাত্র টাস্ক শেষ হওয়া পর্যন্ত অপেক্ষা

using System;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main()
    {
        Task task1 = Task.Delay(2000); // ২ সেকেন্ড অপেক্ষা
        Task task2 = Task.Delay(1000); // ১ সেকেন্ড অপেক্ষা

        await Task.WhenAny(task1, task2); // যেকোনো একটি টাস্ক শেষ হলে পরবর্তী কোড চালাবে

        Console.WriteLine("One of the tasks completed.");
    }
}

Parallel ক্লাসের ব্যবহার

Parallel.For এবং Parallel.ForEach সমান্তরালে লুপ চালানোর জন্য ব্যবহৃত হয়।

উদাহরণ: Parallel.For

using System;
using System.Threading.Tasks;

public class Program
{
    public static void Main()
    {
        Parallel.For(1, 6, i =>
        {
            Console.WriteLine("Parallel Task: " + i);
        });

        Console.WriteLine("Parallel.For loop completed.");
    }
}

উদাহরণ: Parallel.ForEach

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class Program
{
    public static void Main()
    {
        List<string> names = new List<string> { "Alice", "Bob", "Charlie" };

        Parallel.ForEach(names, name =>
        {
            Console.WriteLine("Processing: " + name);
        });

        Console.WriteLine("Parallel.ForEach loop completed.");
    }
}

TPL এর মাধ্যমে টাস্ক ক্যান্সেল করা (Task Cancellation)

কখনো কখনো নির্দিষ্ট শর্তে টাস্ক বন্ধ করা প্রয়োজন হতে পারে। TPL এ CancellationToken এর মাধ্যমে টাস্ক ক্যান্সেল করা যায়।

using System;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main()
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        CancellationToken token = cts.Token;

        Task task = Task.Run(() =>
        {
            for (int i = 1; i <= 5; i++)
            {
                if (token.IsCancellationRequested)
                {
                    Console.WriteLine("Task canceled.");
                    return;
                }

                Console.WriteLine("Task running: " + i);
                Thread.Sleep(1000);
            }
        }, token);

        await Task.Delay(2000); // কিছু সময় অপেক্ষা
        cts.Cancel(); // টাস্ক ক্যান্সেল

        await task;
        Console.WriteLine("Main task completed.");
    }
}

সংক্ষেপে

  • Task: একটি নির্দিষ্ট কাজ চালায় এবং কনকারেন্টলি কাজ সম্পন্ন করে।
  • Task.Run(): নতুন টাস্ক তৈরি এবং চালানো সহজ করে।
  • Task.WhenAll এবং Task.WhenAny: একাধিক টাস্ককে একত্রে বা আলাদাভাবে পরিচালনা করা যায়।
  • Parallel.For এবং Parallel.ForEach: লুপ চালানো সমান্তরালে।
  • CancellationToken: টাস্ক ক্যান্সেল করতে ব্যবহৃত হয়।

Task Parallel Library সি# এ কনকারেন্সি এবং প্যারালালিজমকে সহজ এবং কার্যকর করে তোলে। এটি ব্যবহার করে কার্যক্ষমতা বৃদ্ধি, সমান্তরালে কাজ পরিচালনা, এবং আরও দ্রুত সাড়া প্রদান করা সম্ভব হয়।

Content added By
Promotion